package cn.dakaqi.services.impl;

import cn.dakaqi.dao.ActivityRecruitDao;
import cn.dakaqi.entities.Activity;
import cn.dakaqi.entities.ActivityRecruit;
import cn.dakaqi.entities.IndexData;
import cn.dakaqi.services.ActivityRecruitService;
import cn.dakaqi.services.ActivityService;
import cn.dakaqi.services.IndexDataService;
import cn.dakaqi.services.LogService;
import cn.dakaqi.utils.Clock;
import cn.dakaqi.utils.DKQConstant;
import cn.dakaqi.utils.exception.ServiceRuntimeException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;

import javax.persistence.criteria.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by chunyang on 2016/4/18.
 */
@Component(value = "activityRecruitService")
@Transactional
public class ActivityRecruitServiceImpl implements ActivityRecruitService
{
    SimpleDateFormat DefaultTimeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    @Autowired
    ActivityRecruitDao activityRecruitDao;
    @Autowired
    ActivityService activityService;
    @Autowired
    IndexDataService indexDataService;
    @Autowired
    private LogService logService;

    private void saveLog(String message)
    {
        logService.save(400,message);
    }
    @Override
    public void create(String param) throws ServiceRuntimeException
    {
        JSONObject jsonObject = JSON.parseObject(param);
        String activityCode = jsonObject.getString("activityCode");
        String job = jsonObject.getString("job");
        String skill = jsonObject.getString("skill");
        String serviceField = jsonObject.getString("serviceField");
        String img = jsonObject.getString("img");
        String question = jsonObject.getString("question");

        Activity activity = this.activityService.findByActivityCode(activityCode);
        ActivityRecruit activityRecruit = new ActivityRecruit();
        activityRecruit.setCreateTime(Clock.DEFAULT.getCurrentDate());
        activityRecruit.setActivity(activity);
        activityRecruit.setImg(img);
        activityRecruit.setJob(job);
        activityRecruit.setServiceField(serviceField);
        activityRecruit.setNeeds(activity.getNeeds());
        activityRecruit.setSkill(skill);
        activityRecruit.setQuestion(question);
        activityRecruit.setStatus(DKQConstant.PROCEED_START);
        activityRecruit.setDelStatus(DKQConstant.DEL_NO);
        try
        {
            activityRecruit.setStopTime(DefaultTimeFormatter.parse(activity.getEndTime()));
        } catch (ParseException e)
        {
            e.printStackTrace();
        }
        save(activityRecruit);
    }

    /**
     * 停止招募
     * @param param
     */
    @Override
    public void stop(String param)
    {
        JSONObject jsonObject = JSON.parseObject(param);
        String activityCode = jsonObject.getString("activityCode");
        String memberCode = jsonObject.getString("memberCode");
        stop(activityCode,memberCode);

    }
    @Override
    public void stop(String activityCode,String memberCode)
    {
        ActivityRecruit activityRecruit = this.findByActivityCode(activityCode);
        if(null != activityRecruit)
        {
            Activity activity = activityRecruit.getActivity();
            if(null != activity)
            {
                activity.setActStatus(DKQConstant.ACT_STATUS_INNER);
                this.activityService.update(activity);
            }
            activityRecruit.setDelStatus(DKQConstant.DEL_YES);
            this.activityRecruitDao.save(activityRecruit);

            //取消首页数据
            IndexData indexData = indexDataService.findByActivityRecruit(activityRecruit.getId());
            if(null != indexData)
            {
                indexData.setDelStatus(DKQConstant.DEL_YES);
                this.indexDataService.save(indexData);
            }
        }
    }
    @Override
    public void save(ActivityRecruit activityRecruit) throws ServiceRuntimeException
    {
        //检查当前活动是否已发布招募
        ActivityRecruit temp = findByActivityCode(activityRecruit.getActivity().getActivityCode());
        if(null != temp)
            throw new ServiceRuntimeException("当前活动已发布招募了,不可以重复招募");
        //保存活动招募信息
        this.activityRecruitDao.save(activityRecruit);

        //将活动标识为对外招募状态
        Activity activity = activityRecruit.getActivity();
        activity.setActStatus(DKQConstant.ACT_STATUS_OUTER);
        this.activityService.updateActStatusOuter(activity);

        //将活动招募放入首页自定义的容器中
        IndexData indexData = new IndexData();
        indexData.setType("ActivityRecruit");
        indexData.setCreateTime(Clock.DEFAULT.getCurrentDate());
        indexData.setDisplay(DKQConstant.DISPLAY_YES);
        indexData.setActivityRecruit(activityRecruit);
        indexData.setDelStatus(DKQConstant.DEL_NO);
        indexData.setTop(DKQConstant.TOP_NO);
        indexData.setSkill(activityRecruit.getSkill());
        indexData.setJob(activityRecruit.getJob());
        indexData.setServiceField(activityRecruit.getServiceField());
        indexData.setCity(activityRecruit.getActivity().getCity());
        indexData.setStopStatus(DKQConstant.PROCEED_START);
        try
        {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            indexData.setStopTime(sdf.parse(activityRecruit.getActivity().getStartTime()+":00"));
        } catch (ParseException e)
        {
            e.printStackTrace();
        }
        this.indexDataService.save(indexData);
    }

    @Override
    public void update(ActivityRecruit activityRecruit) throws ServiceRuntimeException
    {
        activityRecruitDao.save(activityRecruit);
    }

    @Override
    public ActivityRecruit findOne(Long id) throws ServiceRuntimeException
    {
        ActivityRecruit activityRecruit = this.activityRecruitDao.findOne(id);
        activityRecruit.setBrowses(activityRecruit.getBrowses()+1);
        this.activityRecruitDao.save(activityRecruit);
        return activityRecruit;
    }

    @Override
    public ActivityRecruit findByActivity(Long activityId) throws ServiceRuntimeException
    {
        //Map<String,Object> map = new HashMap<String, Object>();
        //map.put("LIKE_NAME",name);
        //Map<String, SearchFilter> filters = SearchFilter.parse(map);

        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("activity.id", new SearchFilter("activity.id", SearchFilter.Operator.EQ, activityId));
        filters.put("delStatus", new SearchFilter("delStatus", SearchFilter.Operator.EQ,DKQConstant.DEL_NO));
        Specification<ActivityRecruit> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivityRecruit.class);
        List<ActivityRecruit> list = this.activityRecruitDao.findAll(spec);
        if(null != list && list.size() ==1)
            return list.get(0);
        return null;
    }

    @Override
    public ActivityRecruit findByActivityCode(String activityCode) throws ServiceRuntimeException
    {
        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("activity.activityCode", new SearchFilter("activity.activityCode", SearchFilter.Operator.EQ, activityCode));
        //filters.put("status", new SearchFilter("status", SearchFilter.Operator.EQ,DKQConstant.PROCEED_START));
        filters.put("delStatus", new SearchFilter("delStatus", SearchFilter.Operator.EQ,DKQConstant.DEL_NO));
        Specification<ActivityRecruit> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivityRecruit.class);
        List<ActivityRecruit> list = this.activityRecruitDao.findAll(spec);
        if(null != list && list.size() ==1)
            return list.get(0);
        return null;
    }

    @Override
    public List<ActivityRecruit> findByServiceField(String createTime,String serviceField) throws ServiceRuntimeException
    {
        List<ActivityRecruit> result = new ArrayList<ActivityRecruit>();
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");

        for(String tag:serviceField.split(";"))
        {
            //Map<String,Object> map = new HashMap<String, Object>();
            //map.put("LIKE_NAME",name);
            //Map<String, SearchFilter> filters = SearchFilter.parse(map);

            Map<String, SearchFilter> filters = Maps.newHashMap();
            filters.put("delStatus", new SearchFilter("delStatus", SearchFilter.Operator.EQ,DKQConstant.DEL_NO));
            filters.put("serviceField", new SearchFilter("serviceField", SearchFilter.Operator.LIKE, tag));
            if(StringUtils.isNotBlank(createTime))
                filters.put("createTime", new SearchFilter("createTime", SearchFilter.Operator.GT, createTime));
            Specification<ActivityRecruit> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivityRecruit.class);
            List<ActivityRecruit> temp = this.activityRecruitDao.findAll(spec, sort);
            if(null != temp && temp.size()>0)
                result.addAll(temp);
        }
        List<ActivityRecruit> listWithoutDup = new ArrayList<ActivityRecruit>(new HashSet<ActivityRecruit>(result));
        return listWithoutDup;
    }

    @Override
    public Page<ActivityRecruit> findAll(String createTime,int pageNumber) throws ServiceRuntimeException
    {
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        PageRequest pageRequest = new PageRequest(pageNumber - 1, 20, sort);

        //Map<String,Object> map = new HashMap<String, Object>();
        //map.put("LIKE_NAME",name);
        //Map<String, SearchFilter> filters = SearchFilter.parse(map);

        Map<String, SearchFilter> filters = Maps.newHashMap();
        if(StringUtils.isNotBlank(createTime))
            filters.put("createTime", new SearchFilter("createTime", SearchFilter.Operator.GT, createTime));

        filters.put("delStatus", new SearchFilter("delStatus", SearchFilter.Operator.EQ,DKQConstant.DEL_NO));
        Specification<ActivityRecruit> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivityRecruit.class);
        return this.activityRecruitDao.findAll(spec,pageRequest);
    }

    @Override
    public List<ActivityRecruit> findTitleLike(String title) throws ServiceRuntimeException
    {
        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("activity.name", new SearchFilter("activity.name", SearchFilter.Operator.LIKE, title));
        filters.put("delStatus", new SearchFilter("delStatus", SearchFilter.Operator.EQ,DKQConstant.DEL_NO));
        Specification<ActivityRecruit> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivityRecruit.class);
        return this.activityRecruitDao.findAll(spec);
    }

    @Override
    public List<ActivityRecruit> findByJobSkillSerivice(final String tag) throws ServiceRuntimeException
    {
        return this.activityRecruitDao.findAll(new Specification<ActivityRecruit>()
        {
            @Override
            public Predicate toPredicate(Root<ActivityRecruit> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder)
            {
                Predicate predicate = null;

                //path转化
                List<Predicate> orPredicates = Lists.newArrayList();

                Path<String> _job = root.get("job");
                Path<String> _serviceField = root.get("serviceField");
                Path<String> _skills = root.get("skill");

                orPredicates.add(criteriaBuilder.or(criteriaBuilder.like(_job, tag)));
                orPredicates.add(criteriaBuilder.or(criteriaBuilder.like(_serviceField, tag)));
                orPredicates.add(criteriaBuilder.or(criteriaBuilder.like(_skills, tag)));

                // 将所有条件用 and 联合起来
                if (!orPredicates.isEmpty()) {
                    predicate =  criteriaBuilder.or(orPredicates.toArray(new Predicate[orPredicates.size()]));
                }

                return predicate;
            }
        });
    }

    @Override
    public void updateStatus() throws ServiceRuntimeException
    {
        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("status", new SearchFilter("status", SearchFilter.Operator.EQ, DKQConstant.PROCEED_START));
        Specification<ActivityRecruit> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivityRecruit.class);
        List<ActivityRecruit> list =  this.activityRecruitDao.findAll(spec);
        if(null != list && list.size()>0)
        {
            for(ActivityRecruit ar:list)
            {
                Date today = new Date();
                Date endDate = ar.getStopTime();
                //检查当是否已结束
                if(today.after(endDate))
                {
                    ar.setStatus(DKQConstant.PROCEED_END);
                    this.activityRecruitDao.save(ar);
                }
            }
        }
    }
}
